package com.dcivision.dms.web;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.dcivision.dms.DmsErrorConstant;
import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.bean.DmsValidation;
import com.dcivision.dms.core.DocumentOperationManager;
import com.dcivision.dms.core.DocumentRetrievalManager;
import com.dcivision.dms.core.DocumentValidateManager;
import com.dcivision.dms.core.RootOperationManager;
import com.dcivision.dms.core.RootRetrievalManager;
import com.dcivision.framework.ApplicationContainer;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.web.AbstractListAction;
import com.dcivision.framework.web.AbstractSearchForm;

public class ListDmsRootAction extends AbstractListAction {

  public static final String REVISION = "$Revision: 1.15.2.3 $";


  /**
   *  Constructor - Creates a new instance of ListUserGroupAction and define the default listName.
   */
  public ListDmsRootAction() {
    super();
    this.setListName("dmsRootList");
  }

  /**
   * getMajorDAOClassName
   *
   * @return  The class name of the major DAObject will be used in this action.
   */
  public String getMajorDAOClassName() {
    return("com.dcivision.dms.dao.DmsRootDAObject");
  }

  /**
   *  Method execute() - generaic function of result list handling, including:
   *                     1. Delete record in List
   *                     2. Get List Data
   *
   *  @param      mapping               ActionMapping from struts
   *  @param      form                  ActionForm from struts
   *  @param      request               HttpServletReuqest
   *  @param      respond               HttpServletRespond
   *  @return     ActionForward         Return the action forward object for struts
   *  @throws     ServletException      Throws ServletException
   */
  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException {

    AbstractSearchForm searchForm = findExpectForm4ListAction(mapping, (AbstractSearchForm) form, request);
    log.info(this.getClass().getName()+", OP Mode:"+searchForm.getOpMode()+", Nav Mode:"+searchForm.getNavMode());

    // Set the function code for current action.
    ActionForward forward = this.retrieveFunctionCode(request, response, mapping);
    if (forward!=null) {
      return forward;
    }

    if (GlobalConstant.OP_MODE_LIST_DELETE.equals(searchForm.getOpMode())) {
      try {
        this.deleteListData2(mapping, searchForm, request, response);
        this.commit(request);
        searchForm.setBasicSelectedID(null);
        searchForm.setOpMode(null);

        // Check for all item deletes per page
        this.getListData(mapping, searchForm, request, response);
      } catch (ApplicationException e) {
        this.rollback(request);
        this.handleApplicationException(request, e);
        request.setAttribute(this.m_sListName, new ArrayList());
      }
    } else {
      try {
        this.getListData(mapping, searchForm, request, response);
      } catch (ApplicationException e) {
        this.handleApplicationException(request, e);
        request.setAttribute(this.m_sListName, new ArrayList());
      }
    }

    List resultList = (List)request.getAttribute(this.m_sListName);
    while ( (resultList.size()==0) && (TextUtility.parseInteger(searchForm.getCurStartRowNo())>TextUtility.parseInteger(searchForm.getPageOffset())) ) {
      int prvRowNo = TextUtility.parseInteger(searchForm.getCurStartRowNo())-TextUtility.parseInteger(searchForm.getPageOffset());
      searchForm.setCurStartRowNo(TextUtility.formatInteger(prvRowNo));
      this.getListData(mapping, searchForm, request, response);
    }

    return mapping.findForward(GlobalConstant.NAV_MODE_LIST);
  }  
  
  /**
   * getFunctionCode
   *
   * @return  The corresponding system function code of action.
   */
  public String getFunctionCode() {
    return(SystemFunctionConstant.DMS_ADMIN);
  }

  /**
   * deleteRecord
   *
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  public void deleteListData(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    Connection conn = this.getConnection(request);
    try {
      RootOperationManager rootManager = new RootOperationManager(this.getSessionContainer(request), conn);
      DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(this.getSessionContainer(request), conn);      
      
      String[] selectedID = form.getBasicSelectedID();
      for (int i = 0; i < selectedID.length; i++) {
        if (!Utility.isEmpty(selectedID[i])) {
          List notDeleteDocumentList = rootManager.deletePublicRootExpectSpecDocument(TextUtility.parseIntegerObj(selectedID[i]));          
          if(notDeleteDocumentList !=null &&notDeleteDocumentList.size() != 0 ){
            for(int j = 0 ; j < notDeleteDocumentList.size() ;j++){
              List tempList = (List)notDeleteDocumentList.get(j);                        
              DmsDocument tmpDocument = (DmsDocument)tempList.get(0);
              String tempDeleteType =  (String)tempList.get(1);
              //delete successfull
              if("S".equals( tempDeleteType)){
                this.addMessage(request,DmsErrorConstant.MESSAGE_RECORD_DELETED_SUCCESS,docRetrievalManager.getLocationPath(tmpDocument.getID()));                            
              }   
            }
            
            for(int j = 0 ; j < notDeleteDocumentList.size() ;j++){
              List tempList = (List)notDeleteDocumentList.get(j);                        
              DmsDocument tmpDocument = (DmsDocument)tempList.get(0);
              String tempDeleteType =  (String)tempList.get(1);
              // checkout document not allow delete
              if("C".equals( tempDeleteType)){
                this.addMessage(request,DmsErrorConstant.MESSAGE_RECORD_CHECKOUT_NOTDELETED,docRetrievalManager.getLocationPath(tmpDocument.getID()));                            
              }
            }
            
            for(int j = 0 ; j < notDeleteDocumentList.size() ;j++){
              List tempList = (List)notDeleteDocumentList.get(j);                        
              DmsDocument tmpDocument = (DmsDocument)tempList.get(0);
              String tempDeleteType =  (String)tempList.get(1);
              // not delete permission not allow delete
              if("P".equals( tempDeleteType)){
                this.addMessage(request,DmsErrorConstant.MESSAGE_RECORD_NOTPERMISSION_NOTDELETED,docRetrievalManager.getLocationPath(tmpDocument.getID()));                            
              }
            }   
          }
        }
      }
      rootManager.release();
    } catch (Exception e) {
      log.error(e, e);
    } finally {
      conn = null;
    }
  }
  
  public void deleteListData2(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentValidateManager docValidateManager = new DocumentValidateManager(sessionContainer, conn);
    DocumentOperationManager docOperationManager = new DocumentOperationManager(sessionContainer, conn);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    RootRetrievalManager rootRetrievalManager = new RootRetrievalManager(sessionContainer, conn);
    ApplicationContainer container = (ApplicationContainer)request.getSession().getServletContext().getAttribute(GlobalConstant.APPLICATION_CONTAINER_KEY);
    
    List clipboardList = (List)request.getSession().getAttribute("DMS_CLIPBOARD");
    String[] selectedID = form.getBasicSelectedID();
    boolean isIgnoreDeleteShortcut = ((ListDmsRootForm)form).isIgnoreDeleteShortcut();
    
    //step 1: loop and validate tree node, add id to lstIdHasRight/lstIdMisRight/lstIdBeLocked
    for (int n=0; n<selectedID.length; n++) {
      Integer rootId = TextUtility.parseIntegerObj(selectedID[n]);
      DmsDocument sourceDocument = rootRetrievalManager.getRootDocument(rootId);
      DmsValidation validation = docValidateManager.validateDeleteAction(sourceDocument, isIgnoreDeleteShortcut);
      
      //step 2: begin delete documents
      String cacheKey = "D"+sessionContainer.getSessionID()+""+System.currentTimeMillis();
      try {
        List deleteDocumentIds = validation.getLstIdAccept();
        //step 2.1: check and lock operation id to application cache
        boolean success = container.checkAndLockDocumentOperationID(cacheKey, deleteDocumentIds, "ACDIMU");
        if (!success) {
          this.addError(request, "errors.dms.fail_to_delete", docRetrievalManager.getLocationPath(sourceDocument.getID()));
          this.addError(request, "errors.dms.cannot_edit_now");
        }else {
          //step 2.2: delete documents
          docOperationManager.deleteDocument(sourceDocument, validation);
          
          //step 2.3: message throws
          List lstIdHasRight = validation.getLstIdAccept();
          List lstIdMisRight = validation.getLstIdReject();
          List lstIdBeLocked = validation.getLstIdlocked();
          List lstIdBeDeleted = validation.getLstIdDeleted();
          List lstIdBeArchived = validation.getLstIdArchived();
          List lstIdRelatedShortcut = validation.getLstIdHaveRelationship();
          String locationPath = docRetrievalManager.getLocationPath(sourceDocument.getID());
          if (validation.isSuccess()) {
            this.addMessage(request, "dms.message.document_deleted_success", locationPath, String.valueOf(lstIdHasRight.size()));
          }else {
            this.addError(request, "errors.dms.fail_to_delete", locationPath);
            for (int i=0; i<lstIdMisRight.size(); i++) {
              this.addError(request,"errors.dms.no_permission",docRetrievalManager.getLocationPath((Integer)lstIdMisRight.get(i)));                            
            }
            for (int i=0; i<lstIdBeLocked.size(); i++) {
              this.addError(request,"errors.dms.been_checkout",docRetrievalManager.getLocationPath((Integer)lstIdBeLocked.get(i)));                            
            }
            for (int i=0; i<lstIdBeDeleted.size(); i++) {
              this.addError(request,"errors.dms.been_deleted",docRetrievalManager.getLocationPath((Integer)lstIdBeDeleted.get(i)));                            
            }
            for (int i=0; i<lstIdBeArchived.size(); i++) {
              this.addError(request,"errors.dms.been_archived",docRetrievalManager.getLocationPath((Integer)lstIdBeArchived.get(i)));                            
            }
            for (int i=0; i<lstIdRelatedShortcut.size(); i++) {
              this.addError(request,"errors.dms.has_relationship",docRetrievalManager.getLocationPath((Integer)lstIdRelatedShortcut.get(i)));                            
            }
            if (!Utility.isEmpty(lstIdHasRight)) {
              this.addError(request, "dms.message.document_been_deleted",String.valueOf(lstIdHasRight.size()));
            }
          }
          
          //step 2.4: delete from clipboard if it present
          if (clipboardList!=null && !clipboardList.isEmpty()) {
            for (int i=0; i<clipboardList.size(); i++) {
              if(deleteDocumentIds.contains(clipboardList.get(i))) {
                clipboardList.remove(i--);
              }
            }
          }
        }
      }catch (ApplicationException ex) {
        throw ex;
      }catch (Exception ex) {
        throw new ApplicationException(ex);
      }finally {
        container.unlockDmsDocumentOperationID(cacheKey);
      }
    }
    conn = null;
    sessionContainer = null;
    container = null;
    rootRetrievalManager.release();
    docValidateManager.release();
    docOperationManager.release();
    docRetrievalManager.release();
  }
}